package megrez.job.custom.component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;

import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;
import megrez.job.custom.domain.Config;
import megrez.job.custom.domain.ConfigRepository;
import megrez.job.custom.domain.ConfigService;
import megrez.job.custom.utils.TaskNotFoundException;
import megrez.job.custom.utils.TaskStateException;

/**
 * 计划任务管理
 * 
 * @author Lucky Yang
 * @since 2.6.9
 */
@Component
@RequiredArgsConstructor
public class ScheduledTaskManager {
    private final TaskRegistrar taskRegistrar;
    private final ConfigRepository configRep;
    private final ConfigService configSrc;

    public Task start(String configId) {
        Config config = configSrc.findById(configId);
        Task task = Task.of(config);

        start(task);
        return task;
    }

    public void start(Task task) {
        if (Boolean.TRUE.equals(task.getConfig().getEnabled())) {
            taskRegistrar.register(task);
        } else {
            // 只加入到容器中，不注册任务
            ScheduledTaskContainer.put(task, ScheduledFutureTaskHolder.emptyHolder());
        }
    }

    public Task stop(String configId) {
        Config config = configSrc.findById(configId);
        Task task = Task.of(config);

        stop(task);
        return task;
    }

    public void stop(Task task) {
        if (ScheduledTaskContainer.isStopped(task)) {
            throw new TaskStateException();
        }

        taskRegistrar.unregister(task);
    }

    public List<Task> stopAll() {
        return taskRegistrar.unregisterAll();
    }

    public List<Task> startAll() {
        List<Task> taskStartedList = new ArrayList<>();

        configRep.findAll().stream().map(Task::of).forEach(task -> {
            if (ScheduledTaskContainer.isStarted(task)) {
                return;
            }

            start(task);
            taskStartedList.add(task);
        });

        return taskStartedList;

    }

    public Task getTaskInfo(String configId) {
        Config config = configSrc.findById(configId);
        Optional<Entry<Task, ScheduledFutureTaskHolder>> task = ScheduledTaskContainer.getEntry(config);
        if (task.isEmpty()) {
            throw new TaskNotFoundException();
        }

        return task.get().getKey();
    }
}
